package com.monogo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.beanutils.BeanMap;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class MonogoDB {
	/**
	 * Logger for this class
	 */

	private String path = "db/";
	private static final String _uuid = "_uuid";
	private String SuffixName = ".xml";
	private String dataBaseName;
	private String dataPath;

	/**
	 * 
	 * 
	 * @return
	 */
	public List<String> findTables() {

		try {
			FileInputStream file = new FileInputStream(dataPath);
			SAXBuilder saxBuilder = new SAXBuilder();
			Document document;
			document = saxBuilder.build(file);
			Element root = document.getRootElement();
			Element tables = root.getChild("tables");

			List<Element> table = tables.getChildren();
			if (table != null && table.size() > 0) {
				List<String> tableNames = new ArrayList<String>();
				for (Element element : table) {
					tableNames.add(element.getAttributeValue("name"));
				}
				return tableNames;

			} else {
				return null;
			}

		} catch (Exception e) {

			e.printStackTrace();
			return null;
		}

	}

	/**
	 * 创建表
	 * @param tableName
	 * @return
	 */
	public boolean createTeable(String tableName) {
		try {
			FileInputStream file = new FileInputStream(dataPath);
			SAXBuilder saxBuilder = new SAXBuilder();
			Document document = saxBuilder.build(file);
			Element root = document.getRootElement();
			Element tables = root.getChild("tables");
			Element data = new Element("table");
			data.setAttribute("name", tableName);
			tables.addContent(data);
			XMLOutputter out = new XMLOutputter();
			out.output(document, new FileOutputStream(dataPath));
			file.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 *删除表
	 * @param tableName
	 * @return
	 */
	public boolean dropTable(String tableName) {
		try {
			FileInputStream file = new FileInputStream(dataPath);
			SAXBuilder saxBuilder = new SAXBuilder();
			Document document = saxBuilder.build(file);
			Element root = document.getRootElement();
			Element tables = root.getChild("tables");
			List<Element> table = tables.getChildren();
			if (table != null && table.size() > 0) {
				for (Element element : table) {
					if (tableName.equals(element.getAttributeValue("name"))) {
						tables.removeContent(element);
						break;
					}

				}
			}
			XMLOutputter out = new XMLOutputter();
			out.output(document, new FileOutputStream(dataPath));
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 保存
	 * 
	 * @param tableName
	 * @param ob
	 */

	public void save(String tableName, Object ob) {
		try {
			FileInputStream file = new FileInputStream(dataPath);
			SAXBuilder saxBuilder = new SAXBuilder();
			Document document = saxBuilder.build(file);
			Element root = document.getRootElement();
			Element tables = root.getChild("tables");

			List<Element> table = tables.getChildren();
			if (table != null && table.size() > 0) {
				for (Element element : table) {
					if (tableName.equals(element.getAttributeValue("name"))) {
						BeanMap beanMap = new BeanMap(ob);
						Map map = new HashMap();
						map.putAll(beanMap);
						if (!map.containsKey(_uuid)) {
							map.put(_uuid, UUID.randomUUID().toString());
						}
						Element data = new Element("data");
						data.addContent(JSON.toJSONString(map, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect));
						element.addContent(data);
						break;
					}

				}
			}
			XMLOutputter out = new XMLOutputter();
			out.output(document, new FileOutputStream(dataPath));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 *删除数据
	 * 
	 * @param tableName
	 * @param ob
	 */
	public void deleteData(String tableName, Object ob) {
		try {
			FileInputStream file = new FileInputStream(dataPath);
			SAXBuilder saxBuilder = new SAXBuilder();
			Document document = saxBuilder.build(file);
			Element root = document.getRootElement();
			Element tables = root.getChild("tables");
			@SuppressWarnings("unchecked")
			List<Element> table = tables.getChildren();
			if (table != null && table.size() > 0) {
				for (Element element : table) {
					if (tableName.equals(element.getAttributeValue("name"))) {
						List<Element> data = element.getChildren();
						for (Element element2 : data) {
							Map mp = JSON.parseObject(element2.getText(), Map.class);
							System.out.println(mp);
							BeanMap beanMap = new BeanMap(ob);
							System.out.println(mp.get(_uuid).equals(beanMap.get(_uuid)));
							if (mp.get(_uuid).equals(beanMap.get(_uuid))) {
								element.removeContent(element2);
								break;
							}
						}
					}

				}
			}
			XMLOutputter out = new XMLOutputter();
			out.output(document, new FileOutputStream(dataPath));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 更新数据
	 * 
	 * @param tableName
	 * @param ob
	 */
	public void updateData(String tableName, Object ob) {
		try {
			FileInputStream file = new FileInputStream(dataPath);
			SAXBuilder saxBuilder = new SAXBuilder();
			Document document = saxBuilder.build(file);
			Element root = document.getRootElement();
			Element tables = root.getChild("tables");
			List<Element> table = tables.getChildren();
			if (table != null && table.size() > 0) {
				for (Element element : table) {
					if (tableName.equals(element.getAttributeValue("name"))) {
						List<Element> datas = element.getChildren();
						for (Element element2 : datas) {
							Map mp = JSON.parseObject(element2.getText(), Map.class);
							System.out.println(mp);
							BeanMap beanMap = new BeanMap(ob);
							System.out.println(mp.get(_uuid).equals(beanMap.get(_uuid)));
							if (mp.get(_uuid).equals(beanMap.get(_uuid))) {
								element.removeContent(element2);
								Element data = new Element("data");
								data.addContent(JSON.toJSONString(beanMap, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect));
								element.addContent(data);
								break;
							}
						}
					}

				}
			}
			XMLOutputter out = new XMLOutputter();
			out.output(document, new FileOutputStream(dataPath));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<Map> loadTableDatas(String tableName) {
		try {
			FileInputStream file = new FileInputStream(dataPath);
			SAXBuilder saxBuilder = new SAXBuilder();
			Document document = saxBuilder.build(file);
			Element root = document.getRootElement();
			Element tables = root.getChild("tables");

			List<Element> table = tables.getChildren();
			if (table != null && table.size() > 0) {
				for (Element element : table) {
					if (tableName.equals(element.getAttributeValue("name"))) {
						List<Map> list = new ArrayList<Map>();
						List<Element> data = element.getChildren();
						for (Element element2 : data) {
							Map mp = JSON.parseObject(element2.getText(), Map.class);
							list.add(mp);
						}
						return list;
					}

				}
			}
			XMLOutputter out = new XMLOutputter();
			out.output(document, new FileOutputStream(dataPath));

		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public String getDataBaseName() {
		return dataBaseName;
	}

	public void setDataBaseName(String dataBaseName) {
		this.dataBaseName = dataBaseName;
	}

	public MonogoDB(String dataBaseName) {
		super();
		this.dataBaseName = dataBaseName;
		this.dataPath = this.path + dataBaseName + this.SuffixName;
	}

}
